﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Windows.Controls.Ribbon;
using TeacherLeftHand.Util;
using RichTextBox = Microsoft.Windows.Controls.RichTextBox;
using System.ComponentModel;

namespace CustomControl
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:CustomControl"
    ///
    ///
    /// Step 1b) Using this custom control in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:CustomControl;assembly=CustomControl"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your control in the XAML file.
    ///
    ///     <MyNamespace:CustomControl1/>
    ///
    /// </summary>
    public class RichTextEditor : RichTextBox
    {
        private RibbonWindow _windowParent;

        public ContextMenu TBoxContextMenu = new ContextMenu();
        public MenuItem UndoMenuItem = new MenuItem();
        public MenuItem RedoMenuItem = new MenuItem();
        public MenuItem CutMenuItem = new MenuItem();
        public MenuItem CopyMenuItem = new MenuItem();
        public MenuItem PasteMenuItem = new MenuItem();
        public MenuItem DeleteMenuItem = new MenuItem();
        public MenuItem SelectAllMenuItem = new MenuItem();
       // public CustomContextMenuItem CustomContextItem = new CustomContextMenuItem();
        //public MenuItem FindMenuItem = new MenuItem();
        //public MenuItem ReplaceMenuItem = new MenuItem();
        //public MenuItem GoToMenuItem = new MenuItem();


        public static RoutedEvent UpdateSelected = EventManager.RegisterRoutedEvent("UpdateSelected", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        public static RoutedEvent RichTextEditorTextChangedEvent = EventManager.RegisterRoutedEvent("RichTextEditorTextChanged", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent UndoEvent = EventManager.RegisterRoutedEvent("Undo", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent RedoEvent = EventManager.RegisterRoutedEvent("Redo", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent CutEvent = EventManager.RegisterRoutedEvent("Cut", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent CopyEvent = EventManager.RegisterRoutedEvent("Copy", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent PasteEvent = EventManager.RegisterRoutedEvent("Paste", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent DeleteEvent = EventManager.RegisterRoutedEvent("Delete", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent SelectAllEvent = EventManager.RegisterRoutedEvent("SelectAll", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent FindEvent = EventManager.RegisterRoutedEvent("Find", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent ReplaceEvent = EventManager.RegisterRoutedEvent("Replace", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        //public static RoutedEvent GoToEvent = EventManager.RegisterRoutedEvent("GoTo", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));
        public static RoutedEvent FocusEvent = EventManager.RegisterRoutedEvent("Focus", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(RichTextEditor));

        //static RichTextEditor()
        //{
        //    //DefaultStyleKeyProperty.OverrideMetadata(typeof(RichTextEditor), new FrameworkPropertyMetadata(typeof(RichTextEditor)));
        //}
        public RichTextEditor():base()
        {
            if (DesignerProperties.GetIsInDesignMode(this)) return;
            
            initialize();
            //BorderBrush = Brushes.Transparent;
            //Addhandlers();
           
        }
        //private void Addhandlers()
        //{
        //    this.AddHandler(CustomContextMenuItem.CustomClick, new RoutedEventHandler(MenuItem_Click));
        //    //this.AddHandler(RichTextEditor.RedoEvent, new RoutedEventHandler(RedoMenuItem_Click));

        //    //this.AddHandler(RichTextEditor.FindEvent, new RoutedEventHandler(FindButton_Click));
        //    //this.AddHandler(RichTextEditor.ReplaceEvent, new RoutedEventHandler(ReplaceButton_Click));
        //    //this.AddHandler(DocumentTab.GoToEvent, new RoutedEventHandler(GoToButton_Click));
        //}
        void RichTextEditor_Loaded(object sender, RoutedEventArgs e)
        {
            _windowParent = Utility.TryFindParent<RibbonWindow>(this);

        }

        private void initialize()
        {
            if (CaretPosition.Paragraph != null)
            {
                CaretPosition.Paragraph.LineHeight = 1;
            }
            AcceptsTab = true;
            Margin = new Thickness(-2, -3, 0, 0);
            this.SpellCheck.IsEnabled = true;
            this.SelectionChanged += new RoutedEventHandler(RichTextEditor_SelectionChanged);
            this.TextChanged += new TextChangedEventHandler(RichTextEditor_TextChanged);
            this.GotFocus += new RoutedEventHandler(RichTextEditor_GotFocus);
            this.Loaded += new RoutedEventHandler(RichTextEditor_Loaded);
            ConstruContextMenu();
        }

        void RichTextEditor_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.RaiseEvent(new RoutedEventArgs(RichTextEditorTextChangedEvent));
        }

        void RichTextEditor_GotFocus(object sender, RoutedEventArgs e)
        {
            this.RaiseEvent(new RoutedEventArgs(FocusEvent));
        }
        public void ConstruContextMenu()
        {
            TBoxContextMenu = new ContextMenu();
            //TBoxContextMenu.PlacementTarget = this.this;
            TBoxContextMenu.Opened += new System.Windows.RoutedEventHandler(TBoxContextMenu_Opened);
            var undoimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\undo16.png"));
            var undoicon = new Image();
            var redoimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\redo16.png"));
            var redoicon = new Image();
            var cutimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\cut16.png"));
            var cuticon = new Image();
            var copyimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\copy16.png"));
            var copyicon = new Image();
            var pasteimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\paste16.png"));
            var pasteicon = new Image();
            var deleteimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\delete16.png"));
            var deleteicon = new Image();
            var selectallimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\selectall16.png"));
            var selectallicon = new Image();
            var findimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\find16.png"));
            var findicon = new Image();
            var replaceimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\findreplace16.png"));
            var replaceicon = new Image();
            var gotoimg = new BitmapImage(new Uri(My.MyWpfExtension.Application.Info.DirectoryPath + "\\Images\\Edit\\goto16.png"));
            var gotoicon = new Image();
            undoicon.Width = 16;
            undoicon.Height = 16;
            undoicon.Source = undoimg;
            redoicon.Width = 16;
            redoicon.Height = 16;
            redoicon.Source = redoimg;
            cuticon.Width = 16;
            cuticon.Height = 16;
            cuticon.Source = cutimg;
            copyicon.Width = 16;
            copyicon.Height = 16;
            copyicon.Source = copyimg;
            pasteicon.Width = 16;
            pasteicon.Height = 16;
            pasteicon.Source = pasteimg;
            deleteicon.Width = 16;
            deleteicon.Height = 16;
            deleteicon.Source = deleteimg;
            selectallicon.Width = 16;
            selectallicon.Height = 16;
            selectallicon.Source = selectallimg;
            findicon.Width = 16;
            findicon.Height = 16;
            findicon.Source = findimg;
            replaceicon.Width = 16;
            replaceicon.Height = 16;
            replaceicon.Source = replaceimg;
            gotoicon.Width = 16;
            gotoicon.Height = 16;
            gotoicon.Source = gotoimg;
            UndoMenuItem.Header = "Undo";
            UndoMenuItem.Icon = undoicon;
            RedoMenuItem.Header = "Redo";
            RedoMenuItem.Icon = redoicon;
            CutMenuItem.Header = "Cut";
            CutMenuItem.Icon = cuticon;
            CopyMenuItem.Header = "Copy";
            CopyMenuItem.Icon = copyicon;
            PasteMenuItem.Header = "Paste";
            PasteMenuItem.Icon = pasteicon;
            DeleteMenuItem.Header = "Delete";
            DeleteMenuItem.Icon = deleteicon;
            SelectAllMenuItem.Header = "Select All";
            SelectAllMenuItem.Icon = selectallicon;
            //CustomContextItem.Header = "Custom Context Item";
            //CustomContextItem.Icon = deleteicon;
            //FindMenuItem.Header = "Find";
            //FindMenuItem.Icon = findicon;
            //ReplaceMenuItem.Header = "Replace";
            //ReplaceMenuItem.Icon = replaceicon;
            //GoToMenuItem.Header = "Go To";
            //GoToMenuItem.Icon = gotoicon;
            TBoxContextMenu.Items.Add(UndoMenuItem);
            TBoxContextMenu.Items.Add(RedoMenuItem);
            TBoxContextMenu.Items.Add(new Separator());
            TBoxContextMenu.Items.Add(CutMenuItem);
            TBoxContextMenu.Items.Add(CopyMenuItem);
            TBoxContextMenu.Items.Add(PasteMenuItem);
            TBoxContextMenu.Items.Add(DeleteMenuItem);
            TBoxContextMenu.Items.Add(new Separator());
            TBoxContextMenu.Items.Add(SelectAllMenuItem);
            TBoxContextMenu.Items.Add(new Separator());
            //TBoxContextMenu.Items.Add(CustomContextItem);
            //TBoxContextMenu.Items.Add(FindMenuItem);
            //TBoxContextMenu.Items.Add(ReplaceMenuItem);
            //TBoxContextMenu.Items.Add(GoToMenuItem);
            this.ContextMenu = TBoxContextMenu;

            #region add handler
            //this.AddHandler(MenuItem.MouseLeftButtonDownEvent, new RoutedEventHandler(MenuItem_Click), true);
            //this.AddHandler(RedoMenuItem.Click, new RoutedEventHandler(RedoMenuItem_Click), true);
            //this.AddHandler(RichTextBox.DragOverEvent, new DragEventHandler(rtbPreparation_DragOver), true);
            UndoMenuItem.Click += new RoutedEventHandler(UndoMenuItem_Click);
            RedoMenuItem.Click += new RoutedEventHandler(RedoMenuItem_Click);
            CutMenuItem.Click += new RoutedEventHandler(CutMenuItem_Click);
            CopyMenuItem.Click += new RoutedEventHandler(CopyMenuItem_Click);
            PasteMenuItem.Click += new RoutedEventHandler(PasteMenuItem_Click);
            DeleteMenuItem.Click += new RoutedEventHandler(DeleteMenuItem_Click);
            SelectAllMenuItem.Click += new RoutedEventHandler(SelectAllMenuItem_Click);
            //FindMenuItem.Click += new RoutedEventHandler(FindMenuItem_Click);
            //ReplaceMenuItem.Click += new RoutedEventHandler(ReplaceMenuItem_Click);
            //GoToMenuItem.Click += new RoutedEventHandler(GoToMenuItem_Click);
            //Editor.editor.SelectionChanged += new RoutedEventHandler(TBox_SelectionChanged);
            //this.AddHandler(DocumentEditor.TextBoxHasBeenChanged, new RoutedEventHandler(TextBoxHasBeenChangedHandler));
            #endregion
        }
        //public void DisableContextMenu()
        //{
        //    if(TBoxContextMenu !=null)
        //    {
        //        TBoxContextMenu = null;
        //    }
        //}
        #region event handler
        void RichTextEditor_SelectionChanged(object sender, RoutedEventArgs e)
        {
            this.RaiseEvent(new RoutedEventArgs(UpdateSelected));
        }

        #endregion
        #region ContextMenu
        private void TBoxContextMenu_Opened(object sender, RoutedEventArgs e)
        {
            if (this.CanUndo)
            {
                UndoMenuItem.IsEnabled = true;
            }
            else
            {
                UndoMenuItem.IsEnabled = false;
            }
            if (this.CanRedo)
            {
                RedoMenuItem.IsEnabled = true;
            }
            else
            {
                RedoMenuItem.IsEnabled = false;
            }
            if ((new Microsoft.VisualBasic.Devices.Computer()).Clipboard.ContainsText())
            {
                PasteMenuItem.IsEnabled = true;
            }
            else
            {
                PasteMenuItem.IsEnabled = false;
            }
        }
        private void UndoMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Focus();
            this.Undo();
        }
        //private void MenuItem_Click(object sender, RoutedEventArgs e)
        //{
        //    MessageBox.Show("Custom Context");
        //}
        private void RedoMenuItem_Click(object sender, RoutedEventArgs e)
        {

            this.Focus();
            this.Redo();
        }

        private void CutMenuItem_Click(object sender, RoutedEventArgs e)
        {

            this.Focus();
            this.Cut();
        }

        private void CopyMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Focus();
            this.Copy();
        }

        private void PasteMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Focus();
            this.Paste();
        }

        private void DeleteMenuItem_Click(object sender, RoutedEventArgs e)
        {
            EditingCommands.Delete.Execute(null, this);
        }

        private void SelectAllMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Focus();
            this.SelectAll();
        }

        //private void FindMenuItem_Click(object sender, RoutedEventArgs e)
        //{
        //    var findDialog = new FindDialog(this.Document);
        //    findDialog.Owner = _windowParent;
        //    findDialog.ShowDialog();
        //    if (findDialog.Res == "OK")
        //    {
                
        //        var p = this.FindWordFromPosition(this.CaretPosition.DocumentStart, findDialog.TextBox1.Text);
        //        try
        //        {
        //            this.Selection.Select(p.Start, p.End);
        //        }
        //        catch (Exception)
        //        {
        //            MessageBox.Show("Word not found.");
        //        }
                
        //    }
        //}
        //public TextRange FindWordFromPosition(TextPointer position, string word)
        //{
        //    while (position != null)
        //    {
        //        if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
        //        {
        //            string textRun = position.GetTextInRun(LogicalDirection.Forward);
        //            // Find the starting index of any substring that matches "word".
        //            int indexInRun = textRun.IndexOf(word);
        //            if (indexInRun >= 0)
        //            {
        //                var start = position.GetPositionAtOffset(indexInRun);
        //                if (start != null)
        //                {
        //                    var end = start.GetPositionAtOffset(word.Length);
        //                    if (end != null) return new TextRange(start, end);
        //                }
        //            }
        //        }
        //        position = position.GetNextContextPosition(LogicalDirection.Forward);
        //    }
        //    // position will be null if "word" is not found.
        //    return null;
        //}
        //private void ReplaceMenuItem_Click(object sender, RoutedEventArgs e)
        //{
        //    var replaceDialog = new ReplaceDialog();
        //    replaceDialog.Owner = _windowParent;
        //    replaceDialog.ShowDialog();
        //    if (replaceDialog.Res == "OK")
        //    {
        //        if (replaceDialog.TextBox1 != null)
        //        {
        //            TextRange p = this.FindWordFromPosition(this.Document.ContentStart.DocumentStart, (string)replaceDialog.TextBox1.Text);
        //            try
        //            {
        //                this.Selection.Select(p.Start, p.End);
        //                this.Selection.Text = (string)replaceDialog.TextBox2.Text;
        //            }
        //            catch (Exception)
        //            {
        //                MessageBox.Show("Word not found.");
        //            }
        //        }
        //    }
        //}

        //private void GoToMenuItem_Click(object sender, RoutedEventArgs e)
        //{
        //    var gotodialog = new GoToDialog();
        //    gotodialog.Owner = _windowParent;
        //    gotodialog.ShowDialog();
        //    if (gotodialog.Res == "OK")
        //    {
        //        GoToLine(int.Parse(gotodialog.line));
        //    }
        //}
        //public void CommonGoToButton_Click(object sender, RoutedEventArgs e)
        //{
        //    GoToButton_Click(null, null);
        //    e.Handled = true;
        //}
        //public void GoToLine(int linenumber)
        //{
        //    //var lineStartPosition = Document.ContentStart.DocumentStart.GetLineStartPosition(0);
        //    var startPosition = this.Document.ContentStart.GetLineStartPosition(0);
        //    int @int = 2;
        //    while (true)
        //    {
        //        int count = 0;
        //        if (startPosition != null)
        //        {
        //            startPosition = startPosition.GetLineStartPosition(1, out count);
        //        }
        //        if (count == 0)
        //        {
        //            this.CaretPosition = startPosition;
        //            break;
        //        }
        //        if (linenumber == @int)
        //        {
        //            this.CaretPosition = startPosition;
        //            break;
        //        }
        //        @int++;
        //    }
        //}
        //public void GoToButton_Click(object sender, RoutedEventArgs e)
        //{
        //    var gotodialog = new GoToDialog();
        //    gotodialog.Owner = _windowParent;
        //    gotodialog.ShowDialog();
        //    if (gotodialog.Res == "OK")
        //    {
        //        this.GoToLine(int.Parse(gotodialog.line));
        //    }
        //}
      
        #endregion
        #region Subscript/Superscript
        public void ToggleSubscript()
        {
            var currentAlignment = this.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);
            var newAlignment = (((BaselineAlignment)currentAlignment) == BaselineAlignment.Subscript) ? BaselineAlignment.Baseline : BaselineAlignment.Subscript;
            this.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);
        }

        public void ToggleSuperscript()
        {
            var currentAlignment = this.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);
            var newAlignment = (((BaselineAlignment)currentAlignment) == BaselineAlignment.Superscript) ? BaselineAlignment.Baseline : BaselineAlignment.Superscript;
            this.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);
        }
        #endregion
        #region Strikethrough

        public void ToggleStrikethrough()
        {
            var range = new TextRange(this.Selection.Start, this.Selection.End);
            var textDecorationCollection = (TextDecorationCollection)(this.Selection.GetPropertyValue(Inline.TextDecorationsProperty));
            if (textDecorationCollection == null || !textDecorationCollection.Equals(TextDecorations.Strikethrough))
            {
                textDecorationCollection = TextDecorations.Strikethrough;
            }
            else
            {
                textDecorationCollection = new TextDecorationCollection();
            }
            range.ApplyPropertyValue(Inline.TextDecorationsProperty, textDecorationCollection);
        }

        #endregion
    }
}
